package com.yss.reportworld.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yss.common.core.constant.RequestDataHelper;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.common.core.exception.BusinessException;
import com.yss.common.core.utils.JdbcUtil;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.core.utils.uuid.IdUtils;
import com.yss.common.security.utils.DictUtils;
import com.yss.reportworld.domain.DataCustomer;
import com.yss.reportworld.domain.DataModular;
import com.yss.reportworld.domain.DataReport;
import com.yss.reportworld.domain.DatabaseDispose;
import com.yss.reportworld.enums.ReportWorldEnum;
import com.yss.reportworld.mapper.DataCustomerMapper;
import com.yss.reportworld.mapper.DataModularMapper;
import com.yss.reportworld.mapper.DataReportMapper;
import com.yss.reportworld.service.ICompareDataService;
import com.yss.reportworld.service.IDatabaseDisposeService;
import com.yss.reportworld.service.ISqlScriptService;
import com.yss.reportworld.util.TableInfoUtil;
import com.yss.system.api.domain.SysDictData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;


/**
 * 数据对比接口
 *
 * @author yss
 * @date 2023-04-04
 */
@Slf4j
@Service
public class CompareDataServiceImpl implements ICompareDataService {
    @Autowired
    private IDatabaseDisposeService databaseDisposeService;
    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;
    @Autowired
    private ISqlScriptService sqlScriptService;
    @Autowired
    private DataCustomerMapper dataCustomerMapper;
    @Autowired
    private DataModularMapper dataModularMapper;
    @Autowired
    private DataReportMapper dataReportMapper;

    @Override
    public List<DatabaseDispose> queryCompareDataColum(String code) {
        QueryWrapper<DatabaseDispose> wrapper = new QueryWrapper();
        String tableName = ReportWorldEnum.getEnumDescByCode(code);
        wrapper.eq("TABLE_NAME", tableName);
        wrapper.orderByAsc("ORDER_NUM");
        List<DatabaseDispose> list = databaseDisposeService.list(wrapper);
        Map<String, String> mapTypeNew = new LinkedHashMap<>();
        if (code.startsWith(ReportWorldEnum.RW_DB_SUFFIX.getCode())) {
            mapTypeNew.put("STRMODULAR", "所属模块");
            mapTypeNew.put("STRREPORT", "所属报表");
            mapTypeNew.put("STRCUSTOMER", "所属客户");
            mapTypeNew.put("RW_DB_VERSION", "版本号");
            mapTypeNew.put("RW_DB_STATUS", "状态");
            mapTypeNew.put("RW_DB_ADD_TIME", "添加时间");
            mapTypeNew.put("RW_DB_ADD_USER", "添加人");
            mapTypeNew.put("RW_DB_EDIT_TIME", "修改时间");
            mapTypeNew.put("RW_DB_EDIT_USER", "修改人");
        } else {
            mapTypeNew.put("STRMODULAR", "所属模块");
            mapTypeNew.put("STRREPORT", "所属报表");
            mapTypeNew.put("STRCUSTOMER", "所属客户");
        }
        for (Map.Entry<String, String> entry : mapTypeNew.entrySet()) {
            DatabaseDispose dispose = new DatabaseDispose();
            dispose.setId(IdUtils.fastSimpleUUID());
            dispose.setIsShow(1);
            dispose.setWidth(180);
            dispose.setProp(entry.getKey());
            dispose.setLabel(entry.getValue());
            dispose.setComponentType(null);
            list.add(dispose);
        }
        return list;
    }

    @Override
    public List<Object> queryCompareData(String code, String id) {
        PreparedStatement pStemtSelect = null;
        ResultSet rs = null;
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接信息失败，请稍后重试！");
            }
            String tableName = ReportWorldEnum.getEnumDescByCode(code);
            QueryWrapper<DatabaseDispose> wrapper = new QueryWrapper();
            wrapper.eq("TABLE_NAME", tableName);
            List<DatabaseDispose> listDispose = databaseDisposeService.list(wrapper);
            List<Object> list = new ArrayList<>();
            List<SysDictData> listData = sqlScriptService.getReductionVersion(true);
            for (SysDictData dictData : listData) {
                String versionSuffix = TableInfoUtil.getVersionSuffix(dictData.getDictValue());
                String sql = "SELECT DISTINCT A.* FROM " + tableName + versionSuffix + " A WHERE A.ID='" + id + "'";
                if (code.startsWith(ReportWorldEnum.RW_DB_SUFFIX.getCode())) {
                    sql = "SELECT DISTINCT A.* FROM " + tableName + versionSuffix + " A WHERE A.RW_DB_ID='" + id + "'";
                }
                pStemtSelect = connection.prepareStatement(sql);
                rs = pStemtSelect.executeQuery();
                if (rs.next()) {
                    Map<String, Object> stringMap = new HashMap<>();
                    for (DatabaseDispose dispose : listDispose) {
                        if (StringUtils.isNull(dispose)) {
                            continue;
                        }
                        String colum = dispose.getProp();
                        String columValue = rs.getString(colum);
                        stringMap.put(colum.toUpperCase(), columValue);
                    }
                    if (code.startsWith(ReportWorldEnum.RW_DB_SUFFIX.getCode())) {
                        // 显示信息的所属模块，客户，报表信息
                        this.getModularCustomerReport(code, dictData.getDictValue(), rs.getString("RW_DB_ID"), stringMap);
                        stringMap.put("RW_DB_STATUS", rs.getInt("RW_DB_STATUS"));
                        stringMap.put("RW_DB_VERSION", dictData.getDictLabel());
                        stringMap.put("RW_DB_ADD_TIME", rs.getString("RW_DB_ADD_TIME"));
                        stringMap.put("RW_DB_ADD_USER", rs.getString("RW_DB_ADD_USER"));
                        stringMap.put("RW_DB_EDIT_TIME", rs.getString("RW_DB_EDIT_TIME"));
                        stringMap.put("RW_DB_EDIT_USER", rs.getString("RW_DB_EDIT_USER"));
                    } else {
                        stringMap.put("VERSION", dictData.getDictLabel());
                        this.getModularCustomerReport(code, dictData.getDictValue(), rs.getString("ID"), stringMap);
                    }
                    list.add(stringMap);
                } else {
                    Map<String, Object> stringMap = new HashMap<>();
                    if (code.startsWith(ReportWorldEnum.RW_DB_SUFFIX.getCode())) {
                        stringMap.put("RW_DB_VERSION", dictData.getDictLabel());
                        list.add(stringMap);
                    } else {
                        stringMap.put("VERSION", dictData.getDictLabel());
                        list.add(stringMap);
                    }
                }
                rs.close();
            }
            return list;
        } catch (Exception ex) {
            throw new BusinessException("查询数据失败！" + ex.getMessage());
        } finally {
            try {
                JdbcUtil.close(rs);
                JdbcUtil.close(pStemtSelect);
                JdbcUtil.close(connection);
            } catch (Exception ex) {
                throw new BusinessException("查询数据失败！" + ex.getMessage());
            }
        }
    }


    /**
     * 获取数据对应的模块，客户，报表信息
     *
     * @param version
     * @param columValue
     * @param stringMap
     */
    private void getModularCustomerReport(String code, String version, String columValue, Map<String, Object> stringMap) {
        try {
            TableInfoUtil.handleTableVersion(version);
            // 所属模块
            DataModular dataModular = new DataModular();
            dataModular.setDataId(columValue);
            dataModular.setDataCode(code.toUpperCase());
            List<DataModular> modularList = dataModularMapper.selectPrimaryByDataId(dataModular);
            StringBuffer modularName = new StringBuffer();
            List<String> modularId = new ArrayList<>();
            for (DataModular modular : modularList) {
                modularId.add(modular.getModularId());
                modularName.append(modular.getModularName()).append("/");
            }
            if (StringUtils.isNotBlank(modularName.toString())) {
                stringMap.put("STRMODULAR", modularName.deleteCharAt(modularName.length() - 1).toString());
            }
            stringMap.put("MODULAR", modularId);
            // 所属报表
            DataReport dataReport = new DataReport();
            dataReport.setDataId(columValue);
            dataReport.setDataCode(code.toUpperCase());
            List<DataReport> reportList = dataReportMapper.selectPrimaryByDataId(dataReport);
            StringBuffer reportName = new StringBuffer();
            List<String> reportId = new ArrayList<>();
            for (DataReport report : reportList) {
                reportId.add(report.getReportId());
                reportName.append(report.getReportName()).append("/");
            }
            if (StringUtils.isNotBlank(reportName.toString())) {
                stringMap.put("STRREPORT", reportName.deleteCharAt(reportName.length() - 1).toString());
            }
            stringMap.put("REPORT", reportId);
            // 所属客户
            DataCustomer dataCustomer = new DataCustomer();
            dataCustomer.setDataId(columValue);
            dataCustomer.setDataCode(code.toUpperCase());
            List<DataCustomer> customerList = dataCustomerMapper.selectPrimaryByDataId(dataCustomer);
            StringBuffer customerName = new StringBuffer();
            List<String> customerId = new ArrayList<>();
            for (DataCustomer customer : customerList) {
                customerId.add(customer.getCustomerId());
                customerName.append(customer.getCustomerName()).append("/");
            }
            if (StringUtils.isNotBlank(customerName.toString())) {
                stringMap.put("STRCUSTOMER", customerName.deleteCharAt(customerName.length() - 1).toString());
            }
            stringMap.put("CUSTOMER", customerId);
        } catch (Exception ex) {
            log.error(ex.getMessage());
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

}
